/**
* @brief
*		Find errors and decrease probability of getting errors of the same kind in the future
*		This piece of code won't compile and it doesn't describe an entire algorithm: just part of some page storage
*
* @author
*		AnnaM
*/

#include <Windows.h>
#include <stdio.h>

enum PAGE_COLOR
{//!!!я не понимаю зачем начинать перечисление с 1 если везде дальше с 0...
	PG_COLOR_GREEN, /* page may be released without high overhead */
	PG_COLOR_YELLOW, /* nice to have */
	PG_COLOR_RED	/* page is actively used */
};


/**
 * UINT Key of a page in hash-table (prepared from color and address)
 */
union PageKey
{
	struct
	{
        CHAR	cColor: 8;
		UINT	cAddr: 24;
	};
	UINT	uKey;
};
//!!! не соблюдался приоритет операций
//!!! для void* не определћн оператор <<
/* Prepare from 2 chars the key of the same configuration as in PageKey */
#define CALC_PAGE_KEY( Addr, Color )	(  (Color) + ((UINT)Addr << 8) )


/**
 * Descriptor of a single guest physical page
 */
struct PageDesc
{
	PageKey			uKey;	

	/* list support */
	PageDesc		*next, *prev;
};
///!!! Вместо стрелки была точка
///!!! UNION
#define PAGE_INIT( Desc, Addr, Color )              \
    {                                               \
        (Desc)->uKey.uKey = CALC_PAGE_KEY( Addr, Color ); \
        (Desc)->next = (Desc)->prev = NULL;           \
    }
        

/* storage for pages of all colors */
static PageDesc* PageStrg[ 3 ];

void PageStrgInit()
{
	memset( PageStrg, 0, sizeof(&PageStrg) );
}

PageDesc* PageFind( void* ptr, char color )
{
	for( PageDesc* Pg = PageStrg[color]; Pg; Pg = Pg->next ){	//!!!после for стояла ;
		if( Pg->uKey.uKey == (CALC_PAGE_KEY(ptr,color)) ){		//!!!было не указано какую выбрать переменную из юниона
           return Pg;
		}
	}
    return NULL;
}
void PageRemove(PageDesc* a){
	int b=1;
} //!!!
PageDesc* PageReclaim( UINT cnt )///!!!разыменование NULL, использование неинициализированной переменной, да и вместо while уместнее for. Нет проверки что цвета закончились.
{
	
	PageDesc* Pg =  PageStrg[ color ];
	for(UINT color = 0; ((cnt>0)&&(color<=PG_COLOR_RED)); cnt--)
	{
		if( Pg == NULL )
		{
			color++;
			Pg = PageStrg[ color ];
			cnt++;
			continue;
		}
		Pg = Pg->next;
		PageRemove( PageStrg[ color ] );
		cnt--;
		
	}
	return Pg; 
}
            
PageDesc* PageInit( void* ptr, UINT color ) //!!! вот даже не знаю о чћм речь идћт. если тут и должен быть void* то во всех остальных местах нужно заменить UINT cAddr на void* cAdrr...
{
    PageDesc* pg = new PageDesc;
    if( pg )
	{
        PAGE_INIT(pg, ptr, color);			///!!!была передача указателя на указатель на структуру вместо просто указателя
	}else{									///!!!нельзя использовать конструкцию if(smth) do_smth(); else do_else(); нужно выделять блок if скобками
        printf("Allocation has failed\n");
	}
    return pg;
}

/**
 * Print all mapped pages
 */
void PageDump()
{

	#define PG_COLOR_NAME(clr) #clr
	char* PgColorName[] = 
	{
		PG_COLOR_NAME(PG_COLOR_RED),
		PG_COLOR_NAME(PG_COLOR_YELLOW),
		PG_COLOR_NAME(PG_COLOR_GREEN)
	};

	for(UINT color = 0; color <= PG_COLOR_RED; color++)
	{
		printf("PgStrg[(%s) %u] ********** \n", color, PgColorName[color] );
		for( PageDesc* Pg = PageStrg[color]; Pg != NULL; Pg = Pg->next )		//!!!использование цикла while вместо for, причем с неправильным инкрементом итератора
		{
			if( Pg->uKey.cAddr == NULL )	//!!!присвоение вместо сравнения
				continue;

			printf("Pg :Key = 0x%x, addr %x\n", Pg->uKey.uKey, Pg->uKey.cAddr ); //!!!обращение к адресу и ключу минуя uKey, печать числа используя параметр для указателя
		}
	}
	#undef PG_COLOR_NAME
}
int main(){
	return 0;
}
/*
33
34
50
51
69
70
78
99
102
103
127
128
131


*/
